# -*- coding: utf-8 -*-
from __future__ import annotations
import json, sys
from typing import Any

from prompts import SYSTEM_FC
from tools_fc import TOOLS_SPEC, TOOL_FUNCS
from llm_provider import chat_with_tools

def _safe_json_loads(s: str) -> dict:
    try:
        return json.loads(s)
    except json.JSONDecodeError as e:
        raise ValueError(f"工具参数 JSON 解析失败：{e}")

def _exec_tool(name: str, args_str: str) -> Any:
    if name not in TOOL_FUNCS:
        raise KeyError(f"未知工具：{name}")
    args = _safe_json_loads(args_str) if isinstance(args_str, str) else (args_str or {})
    print(f"[Debug: 执行工具：{name}，参数：{args}]")
    return TOOL_FUNCS[name](**args)

def run_agent_fc(user_input: str, max_steps: int = 3) -> str:
    messages = [{"role": "system", "content": SYSTEM_FC},
                {"role": "user", "content": user_input}]

    for step in range(max_steps):
        reply = chat_with_tools(messages, tools=TOOLS_SPEC, tool_choice="auto")
        # 如果模型直接给出文本答案，且没有工具调用，直接返回
        if (reply.get("content") and not reply.get("tool_calls")):
            return str(reply["content"]).strip()

        # 否则执行 tool_calls（可能有多个）
        if reply.get("tool_calls"):
            # optional：把 assistant 的原始回复也追加进去（即使 content 为 None）
            messages.append({"role": "assistant", "content": reply.get("content") or "", "tool_calls": reply["tool_calls"]})

            tool_msgs = []
            for call in reply["tool_calls"]:
                name = call["function"]["name"]
                args_str = call["function"]["arguments"]
                call_id = call["id"]
                try:
                    result = _exec_tool(name, args_str)
                    tool_msgs.append({"role": "tool", "tool_call_id": call_id, "name": name, "content": json.dumps({"ok": True, "result": result}, ensure_ascii=False)})
                except Exception as e:
                    tool_msgs.append({"role": "tool", "tool_call_id": call_id, "name": name, "content": json.dumps({"ok": False, "error": str(e)}, ensure_ascii=False)})
            messages.extend(tool_msgs)
            # 进入下一轮让模型整合工具结果→最终答复
            continue

        # 若既无 content 也无 tool_calls，则提示重试
        messages.append({"role": "user", "content": "请根据需要调用工具或直接给出答案。"})
    raise RuntimeError("达到最大步数仍未获得答案。")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print('用法: python agent_fc.py "2+3是多少？"')
        sys.exit(1)
    query = " ".join(sys.argv[1:]).strip()
    try:
        ans = run_agent_fc(query)
        print(ans)
    except Exception as e:
        print(f"[Error] {e}")
        sys.exit(2)
